#!/usr/bin/env python3
"""
主分析器模块

整合智能规则引擎和机器学习模型，提供完整的程序设计题目分析和测试用例生成功能。
这是系统的核心入口点，使用增强的语义分析器进行语义分析和测试用例生成。

主要功能：
1. 问题分析：使用增强语义分析器分析程序设计问题
2. 测试用例生成：基于分析结果自动生成测试用例
3. 规则管理：支持动态添加、删除和更新规则
4. 历史记录：记录分析历史和操作统计
5. 结果导出：支持多种格式的结果导出
6. 配置管理：灵活的配置参数管理

技术特点：
- 混合分析：结合规则引擎和机器学习模型
- 智能生成：基于语义分析结果生成测试用例
- 多格式导出：支持JSON、文本、Markdown格式
- 历史追踪：完整的分析历史记录
- 配置灵活：支持多种配置参数

使用场景：
- 程序设计题目分析
- 自动测试用例生成
- 规则库维护和管理
- 教学辅助工具
- 代码质量评估

依赖: enhanced_semantic_analyzer, test_case_generator, json, datetime, typing
"""

import json
from datetime import datetime
from typing import Dict, List, Any, Optional

from enhanced_semantic_analyzer import EnhancedSemanticAnalyzer
from test_case_generator import TestCaseGenerator


class ProgrammingProblemAnalyzer:
    """
    程序设计问题分析器
    
    这是系统的核心组件，整合了语义分析和测试用例生成功能。
    提供完整的程序设计题目分析解决方案。
    
    核心功能：
    1. 问题分析：使用增强语义分析器理解问题
    2. 测试用例生成：基于分析结果生成测试用例
    3. 规则管理：动态管理规则库
    4. 历史记录：追踪分析历史和统计
    5. 结果导出：多格式结果导出
    6. 配置管理：灵活的配置参数
    
    工作流程：
    1. 接收问题描述 → 2. 语义分析 → 3. 生成测试用例 → 4. 记录历史 → 5. 返回结果
    
    使用场景：
    - 程序设计教学辅助
    - 自动测试用例生成
    - 问题类型识别
    - 规则库维护
    """
    
    def __init__(self, config: Optional[Dict[str, Any]] = None):
        """
        初始化程序设计问题分析器
        
        创建分析器实例，配置语义分析器和相关参数。
        支持自定义配置参数以满足不同使用场景的需求。
        
        参数:
            config (Optional[Dict[str, Any]]): 配置参数字典，包含：
                - max_test_cases: 最大测试用例数量，默认20
                - enable_ml_enhancement: 是否启用ML增强，默认False
                - ml_model_path: ML模型文件路径，默认None
                - export_format: 导出格式，默认'json'
                - verbose: 是否显示详细信息，默认True
                
        属性:
            config (Dict): 配置参数字典
            semantic_analyzer (EnhancedSemanticAnalyzer): 增强语义分析器实例
            analysis_history (List): 分析历史记录列表
            
        初始化过程:
            1. 设置配置参数（使用默认配置或用户配置）
            2. 创建增强语义分析器实例
            3. 初始化分析历史记录
        """
        # 设置配置参数
        self.config = config or self._get_default_config()
        
        # 初始化增强语义分析器
        ml_model_path = self.config.get('ml_model_path')
        enable_ml = self.config.get('enable_ml_enhancement', False)
        
        self.semantic_analyzer = EnhancedSemanticAnalyzer(
            ml_model_path=ml_model_path,
            enable_ml=enable_ml
        )
        
        # 初始化分析历史记录
        self.analysis_history = []
    
    def _get_default_config(self) -> Dict[str, Any]:
        """
        获取默认配置参数
        
        提供分析器的默认配置参数，确保在没有用户配置时系统能正常运行。
        这些参数可以根据具体需求进行调整。
        
        返回:
            Dict[str, Any]: 默认配置参数字典，包含：
                - max_test_cases: 最大测试用例数量，默认20
                - enable_ml_enhancement: 是否启用ML增强，默认False
                - ml_model_path: ML模型文件路径，默认None
                - export_format: 导出格式，默认'json'
                - verbose: 是否显示详细信息，默认True
                
        配置说明:
            - max_test_cases: 控制单次分析生成的最大测试用例数量
            - enable_ml_enhancement: 是否启用机器学习模型增强分析
            - ml_model_path: 机器学习模型文件路径
            - export_format: 结果导出的默认格式
            - verbose: 是否在控制台显示详细的分析过程信息
        """
        return {
            'max_test_cases': 20,           # 最大测试用例数量
            'enable_ml_enhancement': False, # 是否启用ML增强
            'ml_model_path': None,          # ML模型文件路径
            'export_format': 'json',        # 导出格式
            'verbose': True                 # 是否显示详细信息
        }
    
    def analyze_problem(self, problem_text: str, 
                       generate_test_cases: bool = True,
                       test_case_count: int = 10) -> Dict[str, Any]:
        """
        分析程序设计问题
        
        这是分析器的核心方法，完成从问题描述到测试用例生成的完整流程。
        使用增强语义分析器理解问题，然后基于分析结果生成测试用例。
        
        参数:
            problem_text (str): 程序设计问题的描述文本
                - 支持中英文混合文本
                - 应包含问题的核心描述和要求
                - 例如："计算两个整数的和"
            generate_test_cases (bool): 是否生成测试用例，默认为True
                - True: 生成测试用例
                - False: 仅进行语义分析
            test_case_count (int): 要生成的测试用例数量，默认为10
                - 范围：1到max_test_cases
                - 超出范围会自动调整
                
        返回:
            Dict[str, Any]: 完整的分析结果字典，包含：
                - success: 分析是否成功
                - timestamp: 分析时间戳
                - analysis_result: 语义分析结果
                - config: 使用的配置参数
                - error: 错误信息（如果失败）
                
        工作流程:
            1. 语义分析：使用增强语义分析器理解问题
            2. 测试用例生成：基于分析结果生成测试用例（可选）
            3. 历史记录：记录分析历史和统计信息
            4. 结果构建：构建完整的返回结果
            
        异常处理:
            - 捕获所有异常并返回错误结果
            - 记录错误信息到历史记录
            - 确保程序不会因异常而崩溃
        """
        # 显示分析开始信息
        if self.config.get('verbose', True):
            print("开始分析程序设计问题...")
        
        try:
            # 1. 语义分析 - 使用增强语义分析器理解问题
            if self.config.get('verbose', True):
                print("正在进行语义理解...")
            analysis_result = self.semantic_analyzer.analyze_problem(problem_text)
            
            # 添加问题描述到分析结果中
            analysis_result['problem_text'] = problem_text
            
            # 2. 生成测试用例 - 基于语义分析结果生成测试用例
            if generate_test_cases:
                if self.config.get('verbose', True):
                    print("正在生成测试用例...")
                
                # 创建测试用例生成器
                test_case_generator = TestCaseGenerator(analysis_result)
                # 生成指定数量的测试用例
                test_cases = test_case_generator.generate_test_cases(test_case_count)
                analysis_result['test_cases'] = test_cases
            
            # 3. 记录分析历史 - 保存分析记录用于统计和追踪
            analysis_record = {
                'timestamp': datetime.now().isoformat(),
                'problem_text': problem_text,
                'operation': analysis_result.get('operation', 'unknown'),
                'test_case_count': len(analysis_result.get('test_cases', [])),
                'success': analysis_result.get('success', False)
            }
            self.analysis_history.append(analysis_record)
            
            # 4. 构建返回结果 - 包含所有分析信息
            result = {
                'success': True,
                'timestamp': datetime.now().isoformat(),
                'analysis_result': analysis_result,
                'config': self.config
            }
            
            # 显示分析完成信息
            if self.config.get('verbose', True):
                print(f"分析完成！识别问题类型: {analysis_result.get('operation', 'unknown')}")
                if generate_test_cases:
                    print(f"生成测试用例: {len(analysis_result.get('test_cases', []))} 个")
            
            return result
            
        except Exception as e:
            # 异常处理 - 捕获所有错误并返回错误结果
            error_result = {
                'success': False,
                'error': str(e),
                'timestamp': datetime.now().isoformat(),
                'problem_text': problem_text
            }
            
            # 显示错误信息
            if self.config.get('verbose', True):
                print(f"分析失败: {e}")
            
            return error_result
    
    def get_system_statistics(self) -> Dict[str, Any]:
        """
        获取系统统计信息
        
        提供分析器的使用统计和性能指标，包括语义分析器统计和分析历史统计。
        这些信息有助于了解系统使用情况和性能表现。
        
        返回:
            Dict[str, Any]: 系统统计信息字典，包含：
                - 语义分析器统计信息
                - analysis_history_count: 分析历史记录数量
                - config: 当前配置参数
                
        统计内容:
            1. 语义分析器统计：ML状态、规则引擎统计等
            2. 分析历史统计：总分析次数、成功率等
            3. 配置信息：当前使用的配置参数
        """
        # 获取语义分析器统计信息
        stats = self.semantic_analyzer.get_statistics()
        # 添加分析历史统计
        stats['analysis_history_count'] = len(self.analysis_history)
        # 添加配置信息
        stats['config'] = self.config
        return stats
    
    def reload_rules(self):
        """
        重新加载规则
        
        重新加载规则库中的所有规则文件，用于规则更新后的刷新。
        这在规则文件被修改后非常有用，无需重启系统即可应用新规则。
        
        功能:
            - 重新加载keywords.json、patterns.json、weights.json等文件
            - 更新内存中的规则数据
            - 显示重新加载状态信息
        """
        # 重新加载语义分析器的规则
        self.semantic_analyzer.reload_rules()
        # 显示重新加载信息
        if self.config.get('verbose', True):
            print("规则已重新加载")
    
    def add_keyword(self, pattern_name: str, keyword: str, weight: int = 5):
        """
        添加关键词到规则引擎
        
        向指定模式添加新的关键词，用于扩展规则库的识别能力。
        
        参数:
            pattern_name (str): 目标模式名称
            keyword (str): 要添加的关键词
            weight (int): 关键词权重，默认为5
            
        返回:
            bool: 添加是否成功
        """
        # 调用语义分析器添加关键词
        result = self.semantic_analyzer.add_keyword(pattern_name, keyword, weight)
        # 显示添加结果
        if self.config.get('verbose', True) and result:
            print(f"已添加关键词 '{keyword}' 到模式 '{pattern_name}'")
        return result
    
    def remove_keyword(self, pattern_name: str, keyword: str):
        """
        从规则引擎删除关键词
        
        从指定模式中删除关键词，用于清理不再需要的关键词。
        
        参数:
            pattern_name (str): 目标模式名称
            keyword (str): 要删除的关键词
            
        返回:
            bool: 删除是否成功
        """
        # 调用语义分析器删除关键词
        result = self.semantic_analyzer.remove_keyword(pattern_name, keyword)
        # 显示删除结果
        if self.config.get('verbose', True) and result:
            print(f"已删除关键词 '{keyword}' 从模式 '{pattern_name}'")
        return result
    
    def save_rules(self):
        """
        保存规则到文件
        
        将当前内存中的规则数据保存到JSON文件中，确保数据持久化。
        
        返回:
            bool: 保存是否成功
        """
        # 调用语义分析器保存规则
        result = self.semantic_analyzer.save_rules()
        # 显示保存结果
        if self.config.get('verbose', True) and result:
            print("规则已保存到文件")
        return result
    
    def extract_keywords_from_text(self, text: str) -> List[tuple]:
        """
        从文本中提取关键词
        
        使用规则引擎从文本中提取关键词，返回关键词及其相关信息。
        
        参数:
            text (str): 要分析的文本
            
        返回:
            List[tuple]: 关键词列表，每个元素包含：
                - 关键词文本
                - 关键词类型
                - 关键词权重
        """
        return self.semantic_analyzer.extract_keywords_from_text(text)
    
    def find_keywords_by_pattern(self, pattern_name: str) -> List[str]:
        """
        根据模式名称查找关键词
        
        查找指定模式下的所有关键词。
        
        参数:
            pattern_name (str): 模式名称
            
        返回:
            List[str]: 该模式下的关键词列表
        """
        return self.semantic_analyzer.find_keywords_by_pattern(pattern_name)
    
    def find_patterns_by_keyword(self, keyword: str) -> List[str]:
        """
        根据关键词查找相关模式
        
        查找包含指定关键词的所有模式。
        
        参数:
            keyword (str): 关键词
            
        返回:
            List[str]: 包含该关键词的模式列表
        """
        return self.semantic_analyzer.find_patterns_by_keyword(keyword)
    
    def clear_history(self):
        """
        清空分析历史记录
        
        清除所有分析历史记录，释放内存空间。
        在需要重新开始统计或清理历史数据时使用。
        """
        self.analysis_history = []
    
    def export_analysis_result(self, result: Dict[str, Any], 
                              format_type: str = 'json') -> str:
        """
        导出分析结果
        
        将分析结果导出为指定格式的字符串，支持多种输出格式。
        用于保存分析结果到文件或进行进一步处理。
        
        参数:
            result (Dict[str, Any]): 分析结果字典
            format_type (str): 导出格式类型，支持：
                - 'json': JSON格式（默认）
                - 'txt': 纯文本格式
                - 'md': Markdown格式
                
        返回:
            str: 格式化后的结果字符串
            
        异常:
            ValueError: 当format_type不支持时抛出
        """
        if format_type == 'json':
            # JSON格式导出
            return json.dumps(result, ensure_ascii=False, indent=2)
        elif format_type == 'txt':
            # 纯文本格式导出
            return self._format_as_text(result)
        elif format_type == 'md':
            # Markdown格式导出
            return self._format_as_markdown(result)
        else:
            # 不支持的格式
            raise ValueError(f"不支持的导出格式: {format_type}")
    
    def _format_as_text(self, result: Dict[str, Any]) -> str:
        """
        格式化为纯文本
        
        将分析结果格式化为易读的纯文本格式，适合在控制台显示或保存到文本文件。
        
        参数:
            result (Dict[str, Any]): 分析结果字典
            
        返回:
            str: 格式化后的纯文本字符串
            
        格式特点:
            - 使用等号分隔线
            - 清晰的层次结构
            - 易于阅读的格式
        """
        lines = []
        # 添加标题
        lines.append("=" * 50)
        lines.append("程序设计问题分析结果")
        lines.append("=" * 50)
        
        if result.get('success'):
            # 成功分析的情况
            analysis = result.get('analysis_result', {})
            lines.append(f"问题类型: {analysis.get('operation', 'unknown')}")
            lines.append(f"输入格式: {analysis.get('input_format', {}).get('description', 'unknown')}")
            lines.append(f"输出格式: {analysis.get('output_format', {}).get('description', 'unknown')}")
            
            # 测试用例信息
            test_cases = analysis.get('test_cases', [])
            lines.append(f"测试用例数量: {len(test_cases)}")
            
            # 详细测试用例
            for i, case in enumerate(test_cases, 1):
                lines.append(f"\n测试用例 {i}:")
                lines.append(f"  描述: {case.get('description', '')}")
                lines.append(f"  输入: {case.get('input')}")
                lines.append(f"  预期输出: {case.get('expected_output')}")
                lines.append(f"  类型: {case.get('type', 'unknown')}")
        else:
            # 分析失败的情况
            lines.append(f"分析失败: {result.get('error', 'unknown error')}")
        
        # 添加结尾分隔线
        lines.append("=" * 50)
        return "\n".join(lines)
    
    def _format_as_markdown(self, result: Dict[str, Any]) -> str:
        """
        格式化为Markdown
        
        将分析结果格式化为Markdown格式，适合在文档、网页或支持Markdown的编辑器中显示。
        
        参数:
            result (Dict[str, Any]): 分析结果字典
            
        返回:
            str: 格式化后的Markdown字符串
            
        格式特点:
            - 使用Markdown语法
            - 清晰的标题层次
            - 代码块格式化
            - 适合文档展示
        """
        lines = []
        # 添加主标题
        lines.append("# 程序设计问题分析结果")
        
        if result.get('success'):
            # 成功分析的情况
            analysis = result.get('analysis_result', {})
            lines.append(f"## 问题类型\n{analysis.get('operation', 'unknown')}")
            lines.append(f"## 输入格式\n{analysis.get('input_format', {}).get('description', 'unknown')}")
            lines.append(f"## 输出格式\n{analysis.get('output_format', {}).get('description', 'unknown')}")
            
            # 测试用例信息
            test_cases = analysis.get('test_cases', [])
            lines.append(f"## 测试用例 ({len(test_cases)}个)")
            
            # 详细测试用例
            for i, case in enumerate(test_cases, 1):
                lines.append(f"### 测试用例 {i}")
                lines.append(f"- **描述**: {case.get('description', '')}")
                lines.append(f"- **输入**: `{case.get('input')}`")
                lines.append(f"- **预期输出**: `{case.get('expected_output')}`")
                lines.append(f"- **类型**: {case.get('type', 'unknown')}")
        else:
            # 分析失败的情况
            lines.append(f"## 分析失败\n{result.get('error', 'unknown error')}")
        
        return "\n".join(lines)


if __name__ == "__main__":
    """
    主程序入口
    
    当直接运行此文件时，会执行主分析器的测试演示。
    演示内容包括：
    1. 创建分析器实例
    2. 分析测试问题
    3. 生成测试用例
    4. 显示分析结果
    
    这个演示帮助用户了解如何使用主分析器进行问题分析和测试用例生成。
    """
    # 创建主分析器实例
    analyzer = ProgrammingProblemAnalyzer()
    
    # 测试问题 - 字符串统计问题
    test_problem = """
    请编写一个函数fun(char *tt,int pp[])（无返回值）,统计在 tt 字符串中从 'a' 到 'z' 的 26 个字母各自出现的次数，并依次放在 pp 所指数组中。
    """
    
    print("测试主分析器...")
    # 分析问题并生成5个测试用例
    result = analyzer.analyze_problem(test_problem, test_case_count=5)
    
    # 显示分析结果
    if result['success']:
        print("分析成功！")
        print(f"问题类型: {result['analysis_result']['operation']}")
        print(f"测试用例数量: {len(result['analysis_result']['test_cases'])}")
    else:
        print(f"分析失败: {result['error']}")